package com.weixing.mall.provider.service.impl;

import com.weixing.mall.base.constant.GlobalConstant;
import com.weixing.mall.base.wrapper.Result;
import com.weixing.mall.base.enums.IsEnableEnum;
import com.weixing.mall.core.utils.RequestUtil;
import com.weixing.mall.provider.api.model.dto.LoginLogDto;
import com.weixing.mall.provider.api.model.dto.UserUpdateDto;
import com.weixing.mall.provider.api.model.vo.SysUserAuthVo;
import com.weixing.mall.provider.api.service.SysUserRpcService;
import com.weixing.mall.core.support.auth.SysAuth;
import com.weixing.mall.provider.enums.MsgFlagEnum;
import com.weixing.mall.util.ip.IpParser;
import com.weixing.oauth2.common.userdetails.IUserAuthService;
import com.weixing.oauth2.common.userdetails.SecurityUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName SysUserAuthServiceImpl
 * @Description
 * @Author Small
 * @Date 2019/12/24 17:18
 * @Version 1.0
 **/
@Component("sysUserAuthService")
public class SysUserAuthServiceImpl implements IUserAuthService {
    @Autowired
    private SysUserRpcService sysUserRpcService;
    @Resource
    private TaskExecutor taskExecutor;

    @Override
    public SecurityUser loadUserByUsername(String loginName) {
        Result<SysUserAuthVo> voResult = sysUserRpcService.loadUserByUserName(loginName);
        SecurityUser securityUser = new SecurityUser();
        if (!voResult.isSuccess()) {
            securityUser.setMsgFlag(MsgFlagEnum.EXCEPTION.getValue());
        } else {
            SysUserAuthVo sysUserVo = voResult.getData();
            if (null != sysUserVo) {
                securityUser.setEnable(IsEnableEnum.ENABLE.getValue().equals(sysUserVo.getIsEnable()));
                securityUser.setMsgFlag(MsgFlagEnum.SUCCESS.getValue());
                securityUser.setLoginName(sysUserVo.getLoginName());
                securityUser.setLoginPwd(sysUserVo.getLoginPwd());
                securityUser.setUserRole(GlobalConstant.UserRole.SYS);
                securityUser.setSensitiveData(wrapperSenExt(sysUserVo));
                securityUser.setExtData(wrapperExt(sysUserVo));

            }else{
                securityUser.setMsgFlag(MsgFlagEnum.FAIL.getValue());
            }
        }

        return securityUser;
    }

    @Override
    public SecurityUser loadUserByOpenId(String openId) {
        return null;
    }

    @Override
    public SecurityUser loadUserByXcxOpenId(String openId) {
        return null;
    }


    private Map<String, Object> wrapperExt(SysUserAuthVo userAuthVo) {
        Map<String, Object> ext = new HashMap<>();
        ext.put("uroles", userAuthVo.getRoles());

        return ext;
    }


    private SysAuth wrapperSenExt(SysUserAuthVo userAuthVo) {
        SysAuth sysExt = new SysAuth();
        sysExt.setUid(userAuthVo.getId());
        sysExt.setUr(userAuthVo.getRoles());
        sysExt.setRealName(userAuthVo.getRealName());
        sysExt.setDataGroup(userAuthVo.getDataGroup());
        sysExt.setRoles(userAuthVo.getRoles());
        return sysExt;
    }

    @Override
    public SecurityUser loadUserByMobile(String mobile) {
        Result<SysUserAuthVo> voResult = sysUserRpcService.loadUserByMobile(mobile);
        SecurityUser securityUser = new SecurityUser();
        if (!voResult.isSuccess()) {
            securityUser.setMsgFlag(MsgFlagEnum.EXCEPTION.getDesp());
        } else {
            SysUserAuthVo sysUserVo = voResult.getData();
            if (null != sysUserVo) {
                securityUser.setEnable(IsEnableEnum.ENABLE.getValue().equals(sysUserVo.getIsEnable()));
                securityUser.setMsgFlag(MsgFlagEnum.SUCCESS.getDesp());
                securityUser.setLoginName(sysUserVo.getMobile());
                securityUser.setLoginPwd(sysUserVo.getLoginPwd());
                securityUser.setUserRole(GlobalConstant.UserRole.SYS);
                securityUser.setSensitiveData(wrapperSenExt(sysUserVo));
                securityUser.setExtData(wrapperExt(sysUserVo));
            }else{
                securityUser.setMsgFlag(MsgFlagEnum.FAIL.getDesp());
            }
        }
        return securityUser;
    }

    @Override
    public Collection<GrantedAuthority> loadAuthority(Long userId) {
        return null;
    }

    @Override
    public UserDetails loadUserByPhoneAndPassword(String phone, String password) {
        return null;
    }

    @Override
    public UserDetails loadUserByPhoneAndSmsCode(String phone, String smsCode) {
        return null;
    }

    @Override
    public void handlerLoginData(HttpServletRequest request, SecurityUser securityUser) {
        String remoteAddr = RequestUtil.getRemoteAddr(request);
        taskExecutor.execute(() -> this.updateUser(request, securityUser, remoteAddr));
        taskExecutor.execute(() -> saveLoginLog(securityUser, remoteAddr));
    }

    private void saveLoginLog(SecurityUser securityUser, String remoteAddr) {
        // 记录登录日志
        LoginLogDto sysLoginLog = new LoginLogDto();
        sysLoginLog.setUserId(((SysAuth) securityUser.getSensitiveData()).getUid());
        sysLoginLog.setUserName(securityUser.getUsername());
        sysLoginLog.setIpAddr(remoteAddr);
        sysLoginLog.setIpLoc(IpParser.parse(remoteAddr));
        sysUserRpcService.saveLoginLog(sysLoginLog);
    }

    private void updateUser(HttpServletRequest request, SecurityUser securityUser, String remoteAddr) {
        // 更新用户信息
        UserUpdateDto sysUser = new UserUpdateDto();
        sysUser.setId(((SysAuth) securityUser.getSensitiveData()).getUid());
        sysUser.setLastLoginIp(remoteAddr);
        sysUser.setLastLoginTime(new Date());
        sysUserRpcService.updateUser(sysUser);
    }
}
